package com.fengmi.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.fengmi.dto.PageDTO;
import com.fengmi.entity.SysUser;
import com.fengmi.mapper.SysUserMapper;
import com.fengmi.service.SysUserService;
import com.fengmi.utils.JwtUtils;
import com.fengmi.utils.RsaUtils;
import com.fengmi.vo.PageResultVO;
import com.fengmi.vo.ResultVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ResourceUtils;
import org.springframework.util.StringUtils;


import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Transactional
public class SysUserServiceImpl implements SysUserService {

    @Autowired
    private SysUserMapper userMapper;

    @Override
    public PageResultVO<SysUser> findAllUserByPage(PageDTO<SysUser> pageDTO) {
        //非空判断
        if (pageDTO == null) {
            return new PageResultVO<>(false, "参数不合法");
        }
        //当前页
        Integer pageNum = pageDTO.getPageNum();
        //每页记录数
        Integer pageSize = pageDTO.getPageSize();
        //进行非空判断
        if (pageNum == null || pageNum <= 0) {
            pageNum = 1;
        }
        if (pageSize == null || pageSize <= 0) {
            pageSize = 5;
        }
        //开始分页
        PageHelper.startPage(pageNum, pageSize);
        //调用mapper层查询
        List<SysUser> brandList = userMapper.findUserByWhere(pageDTO.getWhere());
        //分页信息对象创建，放入查询集合
        PageInfo<SysUser> pageInfo = new PageInfo<>(brandList);
        //创建返回对象
        PageResultVO<SysUser> pageResultVO = new PageResultVO<>(true, "查询成功");
        //设置每页数据
        pageResultVO.setData(pageInfo.getList());
        //设置总页数
        pageResultVO.setTotalPage(pageInfo.getPages());
        //设置总记录数
        pageResultVO.setTotalSize(pageInfo.getTotal());

        return pageResultVO;
    }

    @Override
    public ResultVO addUser(SysUser sysUser) {
        if (sysUser == null) {
            return new ResultVO(false, "参数不合法");
        }
        // 完善信息
        // 创建时间设置
        sysUser.setCreateTime(new Date());

        int i = userMapper.saveAddUserInfo(sysUser);

        return new ResultVO(i == 1 ? true : false, i == 1 ? "添加用户成功" : "添加用户失败");
    }

    @Override
    public ResultVO updateUserEnabled(String userId, Integer enabled) {
        if (StringUtils.isEmpty(userId)) {
            return new ResultVO(false, "参数不合法");
        }
        // 修改状态
        int i = userMapper.updateEnabled(userId, enabled);

        return new ResultVO(i == 1 ? true : false, i == 1 ? "修改用户启用状态成功" : "修改用户启用状态失败");
    }

    @Override
    public ResultVO updateUserInfo(SysUser sysUser) {
        if (sysUser == null) {
            return new ResultVO(false, "参数不合法");
        }

        int i = userMapper.updateUserInfo(sysUser);

        return new ResultVO(i == 1 ? true : false, i == 1 ? "修改用户信息成功" : "修改用户信息失败");
    }

    @Override
    public ResultVO selectUserRolesById(String userId) {
        if (StringUtils.isEmpty(userId)) {
            return new ResultVO(false, "参数不合法");
        }

        List<String> rolesIds = userMapper.findUserRolesByUserId(userId);

        return new ResultVO(true, "success", rolesIds);
    }

    @Override
    public ResultVO allocRolesToUser(String userId, String[] roleIds) {
        if (StringUtils.isEmpty(userId) || roleIds == null || roleIds.length == 0) {
            return new ResultVO(false, "参数不合法");
        }
        // 先做删除操作
        int i1 = userMapper.deleteAllRolesById(userId);
        // 再做添加操作
        int i2 = userMapper.allocRolesToUser(userId, roleIds);
        if (i1 + i2 > 0) {
            return new ResultVO(true, "用户角色分配成功");
        }
        return new ResultVO(true, "用户角色分配失败");
    }

    @Override
    public ResultVO deleteUser(String userId) {
        if (StringUtils.isEmpty(userId)) {
            return new ResultVO(false, "参数不合法");
        }

        int i = userMapper.deleteUserById(userId);

        return new ResultVO(i == 1 ? true : false, i == 1 ? "删除用户信息成功" : "删除用户信息失败");
    }

    @Override
    public ResultVO login(SysUser loginUser) {
        try {
            if (loginUser == null) {
                return new ResultVO(false, "用户名或密码不正确");
            }
            // 通过用户名查询用户是否存在，因为密码再数据库中是密文
            SysUser userInDB = userMapper.findUserByUserName(loginUser.getUserName());
            if (userInDB == null) {
                // 用户不存在
                return new ResultVO(false, "用户名或密码不正确");
            }
            // 用户存在,对比密码
            BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
            // 前一个参数是明文密码，后一个是数据库中的密文密码
            boolean matches = encoder.matches(loginUser.getPassword(), userInDB.getPassword());

            if (!matches) {
                // 密码不匹配
                return new ResultVO(false, "用户名或密码不正确");
            }
            // 密码匹配，颁发令牌
            // 1.获取用户的角色信息
            List<String> rolesList = userMapper.findRolesByUserId(String.valueOf(userInDB.getUserId()));
            String roles = "";
            // 遍历集合
            for (String roleName : rolesList) {
                roles += roleName + ",";
            }
            roles = roles.substring(0, roles.length() - 1);
            // 设置用户的角色信息
            userInDB.setRoles(roles);
            // 2.获取用户的权限信息
            List<String> permissionList = userMapper.findPermissionByUserId(userInDB.getUserId());
            String permissions = "";
            // 遍历集合
            for (String permissionName : permissionList) {
                permissions += permissionName + ",";
            }
            permissions = permissions.substring(0, permissions.length() - 1);
            // 设置用户的权限信息
            userInDB.setPermissions(permissions);
            // token载荷中不要放敏感信息
            userInDB.setPassword("");
            // 3.获取密钥
            PrivateKey privateKey = RsaUtils.getPrivateKey(ResourceUtils.getFile("classpath:rsa_pri").getPath());
            // 4. 颁发令牌
            String token = JwtUtils.generateTokenExpireInMinutes(userInDB, privateKey, 45);
            // 5. 没有异常正常返回
            return new ResultVO(true,"登录成功",token);
        } catch (Exception e) {
            e.printStackTrace();
            return new ResultVO(false, "令牌不合法！！！");
        }
    }

    @Override
    public ResultVO verify(String token) {
        try {
            if (StringUtils.isEmpty(token)){
                return new ResultVO(false,"令牌为空！！！");
            }
            // 获取公钥
            PublicKey publicKey = RsaUtils.getPublicKey(ResourceUtils.getFile("classpath:rsa_pub").getPath());
            // 解密token
            SysUser info = (SysUser) JwtUtils.getInfoFromToken(token, publicKey, SysUser.class);
            // 无异常则令牌有效
            return new ResultVO(true,"令牌有效");
        } catch (Exception e) {
            e.printStackTrace();
            // 异常则令牌无效
            return new ResultVO(false,"令牌无效！！！");
        }
    }

    @Override
    public List<SysUser> findAll() {
        return userMapper.findAll();
    }
}
